Notebook for cell type identity correlations using pairwise genes. Subsetting will be needed since for some of the species we only used the first cell type name (which is what we’re more interested in).

General Setup

Setup chunk

Setup reticulate

knitr::opts_chunk$set(fig.width = 8)
knitr::opts_knit$set(root.dir = normalizePath(".."))
knitr::opts_knit$get("root.dir")
[1] "/nas/groups/treutlein/USERS/tomasgomes/projects/pallium_evo"

Load libraries

library(reticulate)
knitr::knit_engines$set(python = reticulate::eng_python)
py_available(initialize = FALSE)
[1] FALSE
use_python(Sys.which("python"))
py_config()
python:         /home/tpires/bin/miniconda3/bin/python
libpython:      /home/tpires/bin/miniconda3/lib/libpython3.8.so
pythonhome:     /home/tpires/bin/miniconda3:/home/tpires/bin/miniconda3
version:        3.8.3 (default, May 19 2020, 18:47:26)  [GCC 7.3.0]
numpy:          /home/tpires/bin/miniconda3/lib/python3.8/site-packages/numpy
numpy_version:  1.18.5

NOTE: Python version was forced by RETICULATE_PYTHON

Data

Load datasets

library(Seurat)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
Attaching SeuratObject
library(simspec)
library(harmony)
Loading required package: Rcpp
library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
Registered S3 method overwritten by 'cli':
  method     from         
  print.boxx spatstat.geom
── Attaching packages ─────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
✓ ggplot2 3.3.3     ✓ purrr   0.3.4
✓ tibble  3.1.2     ✓ stringr 1.4.0
✓ tidyr   1.1.3     ✓ forcats 0.5.0
✓ readr   1.4.0     
── Conflicts ────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library(ggplot2)
library(uwot)
Loading required package: Matrix

Attaching package: ‘Matrix’

The following objects are masked from ‘package:tidyr’:

    expand, pack, unpack

Load metadatas

lizard_all = readRDS("data/expression/lizard_all_v3.RDS")
turtle_all = readRDS("data/expression/turtle_all_v3.RDS")
axolotl_all = readRDS(file = "data/expression/axolotl/palliumres07_harmony.RDS")

Add metadata

lizard_meta = read.csv("data/annotations/lizard_all_umeta.csv", header = T, row.names = 1)
turtle_meta = read.csv("data/annotations/turtle_all_umeta.csv", header = T, row.names = 1)
axolotl_meta = read.csv("data/annotations/axolotl_all_umeta.csv", header = T, row.names = 1)

Filter data (doublets and odd cells)

lizard_all = AddMetaData(lizard_all, metadata = lizard_meta)
turtle_all = AddMetaData(turtle_all, metadata = turtle_meta)
axolotl_all = AddMetaData(axolotl_all, metadata = axolotl_meta)

Put Seurats in list

turtle_all = turtle_all[,turtle_all$classes!="doublets"]
axolotl_all = axolotl_all[,!axolotl_all$cellclusters %in% c("GABAergic neuron", "ETV1+ neuron", "neuron")]

Ortholog matching

Load necessary orthology data

srat_list = list("paintedturtle" = turtle_all, "axolotl" = axolotl_all, "lizard" = lizard_all)

Function for ortholog matching

ort_alt_ens_list = readRDS(file = "data/eggNOG/ort_alt_ens_list.RDS")
ort_alt_egg_list = readRDS(file = "data/eggNOG/ort_alt_egg_list.RDS")

ort_list_use = c(ort_alt_ens_list, 
                 ort_alt_egg_list[which(grepl("axolotl", names(ort_alt_egg_list)) |
                                          grepl("lizard", names(ort_alt_egg_list)))])
bfmats = ort_alt_egg_list[which(grepl("zebrafinch", names(ort_alt_egg_list)))]
names(bfmats) = gsub("zebrafinch", "bengalesefinch", names(bfmats))
ort_list_use = c(ort_list_use, bfmats)

Function for subsetting Seurats

# get orthologs for all species pairs
ortMatch = function(ort_l, sp_vec, ort_scope = "ortholog_one2one"){
  sp_p_mat = combn(sp_vec, 2)
  for(i in 1:ncol(sp_p_mat)){
    sp_pair = sp_p_mat[,i]
    ort_tab = ort_l[[paste0(sp_pair, collapse = ".vs.")]]
    if(!is.null(ort_scope)){
      ort_tab = ort_tab[ort_tab$homology.type==ort_scope,]
    }

    colnames(ort_tab) = gsub("genename", "", colnames(ort_tab))
    if(i==1){
      ort_all = unique(ort_tab[,c(2,4)])
    } else{
      ort_all = unique(merge(ort_all, unique(ort_tab[,c(2,4)]), 
                             by = intersect(colnames(ort_all), colnames(ort_tab))))
    }
  }
  
  return(ort_all)
}

Get ortholog-matched Seurats

seuratOrthologs = function(s_l, o_all){
  # only orthologs present in the Seurat objects
  for(sp in names(s_l)){
    o_all = o_all[o_all[,sp] %in% rownames(s_l[[sp]]),]
  }
  
  # get a unique name for the genes
  allg = unlist(o_all)
  jointnames = c()
  rep_n = list()
  for(i in 1:nrow(o_all)){
    nname = unlist(lapply(o_all[i,], function(x) sum(allg==x)))
    g = unlist(o_all[i,names(nname[nname==1])])
    # if there are acceptable unique names
    if(any(nname==1) & (!is.null(g) & !all(grepl("..", g, fixed = T)))){ # no weird axololt annot
      g = g[!grepl("..", g, fixed = T)] # no weird axololt annot
      g = c(g[!grepl("LOC", g)], g[grepl("LOC", g)])[1] #prioritize non-LOC
      jointnames = c(jointnames, g)
      rep_n[[g]] = 1
    } else{ # we'll add a number to those names
      g = unlist(o_all[i,])
      g = g[!grepl("..", g, fixed = T)] # no weird axololt annot
      g = c(g[!grepl("LOC", g)], g[grepl("LOC", g)])[1] #prioritize non-LOC
      if(g %in% names(rep_n)){
        gn = rep_n[[g]]
        rep_n[[g]] = gn+1
        jointnames = c(jointnames, paste0(g, "-", gn+1))
      } else{
        rep_n[[g]] = 1
        jointnames = c(jointnames, paste0(g, "-", 1))
      }
    }
  }
  
  # filter the Seurats by the orthologs
  ## this requires redoing the Seurat with new names, since some genes will be duplicated
  for(sp in names(s_l)){
    cnts = s_l[[sp]]@assays$RNA@counts[o_all[,sp],]
    rownames(cnts) = jointnames
    m = s_l[[sp]]@meta.data
    s_l[[sp]] = CreateSeuratObject(cnts, project = sp, meta.data = m)
  }
  
  return(s_l)
}

Integration

Normalise data

for(sp in names(srat_ort)){
  print(sp)
  srat_ort[[sp]] = suppressWarnings(SCTransform(srat_ort[[sp]], do.correct.umi = T, verbose = F,
                                                seed.use = 1, vars.to.regress = "nCount_RNA",
                                                variable.features.rv.th = 1, return.only.var.genes = F,
                                                variable.features.n = NULL))
  srat_ort1[[sp]] = suppressWarnings(SCTransform(srat_ort1[[sp]], do.correct.umi = T, verbose = F,
                                                 seed.use = 1, vars.to.regress = "nCount_RNA",
                                                 variable.features.rv.th = 1, return.only.var.genes = F,
                                                 variable.features.n = NULL))
}

Seurats with all merged

for(sp in names(srat_ort)){
  print(sp)
  srat_ort[[sp]] = suppressWarnings(SCTransform(srat_ort[[sp]], do.correct.umi = T, verbose = F,
                                                seed.use = 1, vars.to.regress = "nCount_RNA",
                                                variable.features.rv.th = 1, return.only.var.genes = F,
                                                variable.features.n = NULL))
  srat_ort1[[sp]] = suppressWarnings(SCTransform(srat_ort1[[sp]], do.correct.umi = T, verbose = F,
                                                 seed.use = 1, vars.to.regress = "nCount_RNA",
                                                 variable.features.rv.th = 1, return.only.var.genes = F,
                                                 variable.features.n = NULL))
}
[1] "paintedturtle"
[1] "axolotl"
[1] "lizard"

Seurat rPCA

Integration with all ortholog

srat_ort_all = Reduce(merge, srat_ort)
srat_ort_all = AddMetaData(srat_ort_all, 
                           metadata = unlist(lapply(names(srat_ort), 
                                                    function(x) rep(x, ncol(srat_ort[[x]])))),
                           col.name = "species")

srat_ort1_all = Reduce(merge, srat_ort1)
srat_ort1_all = AddMetaData(srat_ort1_all, 
                           metadata = unlist(lapply(names(srat_ort1), 
                                                    function(x) rep(x, ncol(srat_ort1[[x]])))),
                           col.name = "species")

Integration with one2one ortholog

feat_list = list("all" = rownames(srat_ort1_all@assays$SCT@scale.data), 
                 "allvar" = unique(unlist(lapply(srat_ort1, VariableFeatures))), 
                 "commonvar" = Reduce(intersect, lapply(srat_ort1, VariableFeatures)))
varindat = lapply(srat_ort1, function(x) feat_list$allvar %in% rownames(x))
feat_list$allvar = feat_list$allvar[rowSums(Reduce(cbind, varindat))==length(srat_ort1)]
srat_rpca_one_l = list()
for(n in names(feat_list)){
  print(n)
  integr_feat = feat_list[[n]]
  
  # calculate possible missing Pearson residuals for SCTransform
  srat_ort1_int = PrepSCTIntegration(srat_ort1, anchor.features = integr_feat, verbose = T)
  
  srat_ort1_int <- lapply(X = srat_ort1_int, FUN = function(x) {
    x <- ScaleData(x, features = integr_feat, verbose = FALSE)
    x <- RunPCA(x, features = integr_feat, verbose = FALSE)
  })
  
  # finding the anchors for integration
  all_cell_anchors = FindIntegrationAnchors(srat_ort1_int, normalization.method = "SCT", 
                                            anchor.features = integr_feat, reduction = "rpca",
                                            assay = rep("SCT", length(srat_ort1_int)), 
                                            dims = 1:50, verbose = T)
  
  # actual data integration
  allgenes = rownames(srat_ort1_int[[1]]@assays$RNA@counts)
  all_cell_integr = IntegrateData(all_cell_anchors, normalization.method = "SCT", dims = 1:50,
                                  verbose = T, features.to.integrate = allgenes)
  
  # run PCA and UMAP to see how it looks
  all_cell_integr = RunPCA(all_cell_integr, verbose = F)
  all_cell_integr = RunUMAP(all_cell_integr, dims = 1:30)
  
  all_cell_integr = AddMetaData(all_cell_integr, 
                             metadata = unlist(lapply(names(srat_ort1), 
                                                      function(x) rep(x, ncol(srat_ort1[[x]])))),
                             col.name = "species")
  srat_rpca_one_l[[n]] = all_cell_integr
}

Harmony

Integration with all ortholog

feat_list = list("all" = rownames(srat_ort_all@assays$SCT@scale.data), 
                 "allvar" = unique(unlist(lapply(srat_ort, VariableFeatures))), 
                 "commonvar" = Reduce(intersect, lapply(srat_ort, VariableFeatures)))
varindat = lapply(srat_ort, function(x) feat_list$allvar %in% rownames(x))
feat_list$allvar = feat_list$allvar[rowSums(Reduce(cbind, varindat))==length(srat_ort)]
srat_harm_all_l = list()
for(n in names(feat_list)){
  print(n)
  # Renormalise
  integr_feat = feat_list[[n]]
  VariableFeatures(srat_ort_all) = integr_feat
  srat_ort_all_int = ScaleData(srat_ort_all, features = integr_feat, use.umi = T,
                               do.scale = F, verbose = FALSE)
  srat_ort_all_int = RunPCA(srat_ort_all_int, verbose = FALSE, assay = "SCT", npcs = 50,
                            features = integr_feat)
  
  # Run Harmony
  srat_ort_all_int = RunHarmony(srat_ort_all_int, "species", tau = 30, 
                                plot_convergence = F, assay.use = "SCT")
  
  # Run UMAP on Harmony dimensions
  srat_ort_all_int = RunUMAP(srat_ort_all_int, reduction = "harmony", dims = 1:10)
  
  srat_harm_all_l[[n]] = srat_ort_all_int
}

Integration with one2one ortholog

feat_list = list("all" = rownames(srat_ort1_all@assays$SCT@scale.data), 
                 "allvar" = unique(unlist(lapply(srat_ort1, VariableFeatures))), 
                 "commonvar" = Reduce(intersect, lapply(srat_ort1, VariableFeatures)))
varindat = lapply(srat_ort1, function(x) feat_list$allvar %in% rownames(x))
feat_list$allvar = feat_list$allvar[rowSums(Reduce(cbind, varindat))==length(srat_ort1)]
srat_harm_one_l = list()
for(n in names(feat_list)){
  print(n)
  # Renormalise
  integr_feat = feat_list[[n]]
  VariableFeatures(srat_ort1_all) = integr_feat
  srat_ort1_all_int = ScaleData(srat_ort1_all, features = integr_feat, use.umi = T,
                               do.scale = F, verbose = FALSE)
  srat_ort1_all_int = RunPCA(srat_ort1_all_int, verbose = FALSE, assay = "SCT", npcs = 50,
                            features = integr_feat)
  
  # Run Harmony
  srat_ort1_all_int = RunHarmony(srat_ort1_all_int, "species", tau = 30, 
                                 plot_convergence = F, assay.use = "SCT")
  
  # Run UMAP on Harmony dimensions
  srat_ort1_all_int = RunUMAP(srat_ort1_all_int, reduction = "harmony", dims = 1:10)
  
  srat_harm_one_l[[n]] = srat_ort1_all_int
}

CSS

Integration with all ortholog

feat_list = list("all" = rownames(srat_ort_all@assays$SCT@scale.data), 
                 "allvar" = unique(unlist(lapply(srat_ort, VariableFeatures))), 
                 "commonvar" = Reduce(intersect, lapply(srat_ort, VariableFeatures)))
varindat = lapply(srat_ort, function(x) feat_list$allvar %in% rownames(x))
feat_list$allvar = feat_list$allvar[rowSums(Reduce(cbind, varindat))==length(srat_ort)]
srat_css_all_l = list()
for(n in names(feat_list)){
  print(n)
  integr_feat = feat_list[[n]]
  VariableFeatures(srat_ort_all) = integr_feat
  srat_ort_all_int = ScaleData(srat_ort_all, features = integr_feat, use.umi = T,
                               do.scale = F, verbose = FALSE)
  srat_ort_all_int = RunPCA(srat_ort_all_int, verbose = FALSE, assay = "SCT", npcs = 50,
                            features = integr_feat)
  
  # Run CSS
  srat_ort_all_int = cluster_sim_spectrum(srat_ort_all_int, label_tag="species", redo_pca = T, 
                                          dims_use = 1:30, var_genes = integr_feat)
  
  # Run UMAP on CSS dimensions
  srat_ort_all_int = RunUMAP(srat_ort_all_int, reduction="css", reduction.name="umap_css",
                             dims = 1:ncol(Embeddings(srat_ort_all_int,"css")), reduction.key="UMAPCSS_")
  srat_ort_all_int = SetIdent(srat_ort_all_int, value = "species")
  
  srat_css_all_l[[n]] = srat_ort_all_int
}

Integration with one2one ortholog

feat_list = list("all" = rownames(srat_ort_all@assays$SCT@scale.data), 
                 "allvar" = unique(unlist(lapply(srat_ort, VariableFeatures))), 
                 "commonvar" = Reduce(intersect, lapply(srat_ort, VariableFeatures)))
varindat = lapply(srat_ort, function(x) feat_list$allvar %in% rownames(x))
feat_list$allvar = feat_list$allvar[rowSums(Reduce(cbind, varindat))==length(srat_ort)]
srat_css_all_l = list()
for(n in names(feat_list)){
  print(n)
  integr_feat = feat_list[[n]]
  VariableFeatures(srat_ort_all) = integr_feat
  srat_ort_all_int = ScaleData(srat_ort_all, features = integr_feat, use.umi = T,
                               do.scale = F, verbose = FALSE)
  srat_ort_all_int = RunPCA(srat_ort_all_int, verbose = FALSE, assay = "SCT", npcs = 50,
                            features = integr_feat)
  
  # Run CSS
  srat_ort_all_int = cluster_sim_spectrum(srat_ort_all_int, label_tag="species", redo_pca = T, 
                                          dims_use = 1:30, var_genes = integr_feat)
  
  # Run UMAP on CSS dimensions
  srat_ort_all_int = RunUMAP(srat_ort_all_int, reduction="css", reduction.name="umap_css",
                             dims = 1:ncol(Embeddings(srat_ort_all_int,"css")), reduction.key="UMAPCSS_")
  srat_ort_all_int = SetIdent(srat_ort_all_int, value = "species")
  
  srat_css_all_l[[n]] = srat_ort_all_int
}
[1] "all"
Start to do clustering for each sample...
>> Redoing truncated PCA on sample axolotl...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 16415
Number of edges: 611282

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.9237
Number of communities: 20
Elapsed time: 2 seconds
>> Done clustering of sample axolotl.
>> Redoing truncated PCA on sample lizard...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 4187
Number of edges: 160419

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8918
Number of communities: 11
Elapsed time: 0 seconds
>> Done clustering of sample lizard.
>> Redoing truncated PCA on sample paintedturtle...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 18664
Number of edges: 619386

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8942
Number of communities: 15
Elapsed time: 2 seconds
1 singletons identified. 14 final clusters.
>> Done clustering of sample paintedturtle.
Finished clustering.
Obtained average profiles of clusters.
Start to calculate standardized similarities to clusters...
Doing z-transformation...
Done.
23:28:48 UMAP embedding parameters a = 0.9922 b = 1.112
23:28:48 Read 39266 rows and found 45 numeric columns
23:28:48 Using Annoy for neighbor search, n_neighbors = 30
23:28:48 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
23:28:57 Writing NN index file to temp file /tmp/RtmpyIf2G8/file2bdbd14969e74
23:28:57 Searching Annoy index using 1 thread, search_k = 3000
23:29:10 Annoy recall = 100%
23:29:13 Commencing smooth kNN distance calibration using 1 thread
23:29:17 Initializing from normalized Laplacian + noise
23:29:21 Commencing optimization for 200 epochs, with 1762176 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
23:30:11 Optimization finished
[1] "allvar"
Start to do clustering for each sample...
>> Redoing truncated PCA on sample axolotl...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 16415
Number of edges: 613106

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.9233
Number of communities: 19
Elapsed time: 2 seconds
>> Done clustering of sample axolotl.
>> Redoing truncated PCA on sample lizard...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 4187
Number of edges: 160511

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8930
Number of communities: 11
Elapsed time: 0 seconds
>> Done clustering of sample lizard.
>> Redoing truncated PCA on sample paintedturtle...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 18664
Number of edges: 615768

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8890
Number of communities: 14
Elapsed time: 2 seconds
1 singletons identified. 13 final clusters.
>> Done clustering of sample paintedturtle.
Finished clustering.
Obtained average profiles of clusters.
Start to calculate standardized similarities to clusters...
Doing z-transformation...
Done.
23:40:23 UMAP embedding parameters a = 0.9922 b = 1.112
23:40:23 Read 39266 rows and found 43 numeric columns
23:40:23 Using Annoy for neighbor search, n_neighbors = 30
23:40:23 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
23:40:29 Writing NN index file to temp file /tmp/RtmpyIf2G8/file2bdbd16b007fa
23:40:29 Searching Annoy index using 1 thread, search_k = 3000
23:40:42 Annoy recall = 100%
23:40:44 Commencing smooth kNN distance calibration using 1 thread
23:40:48 Initializing from normalized Laplacian + noise
23:40:52 Commencing optimization for 200 epochs, with 1764938 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
23:41:42 Optimization finished
[1] "commonvar"
Start to do clustering for each sample...
>> Redoing truncated PCA on sample axolotl...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 16415
Number of edges: 612295

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.9173
Number of communities: 16
Elapsed time: 2 seconds
>> Done clustering of sample axolotl.
>> Redoing truncated PCA on sample lizard...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 4187
Number of edges: 169158

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8871
Number of communities: 10
Elapsed time: 0 seconds
>> Done clustering of sample lizard.
>> Redoing truncated PCA on sample paintedturtle...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 18664
Number of edges: 642681

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8838
Number of communities: 14
Elapsed time: 2 seconds
>> Done clustering of sample paintedturtle.
Finished clustering.
Obtained average profiles of clusters.
Start to calculate standardized similarities to clusters...
Doing z-transformation...
Done.
23:44:05 UMAP embedding parameters a = 0.9922 b = 1.112
23:44:05 Read 39266 rows and found 40 numeric columns
23:44:05 Using Annoy for neighbor search, n_neighbors = 30
23:44:05 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
23:44:11 Writing NN index file to temp file /tmp/RtmpyIf2G8/file2bdbd148aac04
23:44:11 Searching Annoy index using 1 thread, search_k = 3000
23:44:24 Annoy recall = 100%
23:44:25 Commencing smooth kNN distance calibration using 1 thread
23:44:29 Initializing from normalized Laplacian + noise
23:44:33 Commencing optimization for 200 epochs, with 1796060 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
23:45:23 Optimization finished

Combined

rPCA + Harmony, all ortholog

feat_list = list("all" = rownames(srat_ort1_all@assays$SCT@scale.data), 
                 "allvar" = unique(unlist(lapply(srat_ort1, VariableFeatures))), 
                 "commonvar" = Reduce(intersect, lapply(srat_ort1, VariableFeatures)))
varindat = lapply(srat_ort1, function(x) feat_list$allvar %in% rownames(x))
feat_list$allvar = feat_list$allvar[rowSums(Reduce(cbind, varindat))==length(srat_ort1)]
srat_css_one_l = list()
for(n in names(feat_list)){
  print(n)
  integr_feat = feat_list[[n]]
  VariableFeatures(srat_ort1_all) = integr_feat
  srat_ort1_all_int = ScaleData(srat_ort1_all, features = integr_feat, use.umi = T,
                               do.scale = F, verbose = FALSE)
  srat_ort1_all_int = RunPCA(srat_ort1_all_int, verbose = FALSE, assay = "SCT", npcs = 50,
                            features = integr_feat)
  
  # Run CSS
  srat_ort1_all_int = cluster_sim_spectrum(srat_ort1_all_int, label_tag="species", redo_pca = T, 
                                          dims_use = 1:30, var_genes = integr_feat)
  
  # Run UMAP on CSS dimensions
  srat_ort1_all_int = RunUMAP(srat_ort1_all_int, reduction="css", reduction.name="umap_css",
                             dims = 1:ncol(Embeddings(srat_ort1_all_int,"css")),
                             reduction.key="UMAPCSS_")
  srat_ort1_all_int = SetIdent(srat_ort1_all_int, value = "species")
  
  srat_css_one_l[[n]] = srat_ort1_all_int
}
[1] "all"
Start to do clustering for each sample...
>> Redoing truncated PCA on sample axolotl...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 16415
Number of edges: 640464

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.9261
Number of communities: 20
Elapsed time: 2 seconds
>> Done clustering of sample axolotl.
>> Redoing truncated PCA on sample lizard...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 4187
Number of edges: 163557

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8957
Number of communities: 11
Elapsed time: 0 seconds
>> Done clustering of sample lizard.
>> Redoing truncated PCA on sample paintedturtle...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 18664
Number of edges: 626082

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8882
Number of communities: 13
Elapsed time: 3 seconds
>> Done clustering of sample paintedturtle.
Finished clustering.
Obtained average profiles of clusters.
Start to calculate standardized similarities to clusters...
Doing z-transformation...
Done.
23:55:34 UMAP embedding parameters a = 0.9922 b = 1.112
23:55:34 Read 39266 rows and found 44 numeric columns
23:55:34 Using Annoy for neighbor search, n_neighbors = 30
23:55:34 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
23:55:40 Writing NN index file to temp file /tmp/RtmpyIf2G8/file2bdbd3ecb81da
23:55:40 Searching Annoy index using 1 thread, search_k = 3000
23:55:53 Annoy recall = 100%
23:55:55 Commencing smooth kNN distance calibration using 1 thread
23:55:59 Initializing from normalized Laplacian + noise
23:56:03 Commencing optimization for 200 epochs, with 1777116 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
23:56:53 Optimization finished
[1] "allvar"
Start to do clustering for each sample...
>> Redoing truncated PCA on sample axolotl...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 16415
Number of edges: 645110

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.9265
Number of communities: 21
Elapsed time: 2 seconds
>> Done clustering of sample axolotl.
>> Redoing truncated PCA on sample lizard...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 4187
Number of edges: 165059

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8960
Number of communities: 11
Elapsed time: 0 seconds
>> Done clustering of sample lizard.
>> Redoing truncated PCA on sample paintedturtle...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 18664
Number of edges: 622418

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8864
Number of communities: 12
Elapsed time: 2 seconds
>> Done clustering of sample paintedturtle.
Finished clustering.
Obtained average profiles of clusters.
Start to calculate standardized similarities to clusters...
Doing z-transformation...
Done.
00:04:34 UMAP embedding parameters a = 0.9922 b = 1.112
00:04:34 Read 39266 rows and found 44 numeric columns
00:04:34 Using Annoy for neighbor search, n_neighbors = 30
00:04:34 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:04:40 Writing NN index file to temp file /tmp/RtmpyIf2G8/file2bdbd505d4a3f
00:04:40 Searching Annoy index using 1 thread, search_k = 3000
00:04:54 Annoy recall = 100%
00:04:55 Commencing smooth kNN distance calibration using 1 thread
00:04:59 Initializing from normalized Laplacian + noise
00:05:03 Commencing optimization for 200 epochs, with 1777102 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:05:53 Optimization finished
[1] "commonvar"
Start to do clustering for each sample...
>> Redoing truncated PCA on sample axolotl...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 16415
Number of edges: 623330

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.9174
Number of communities: 17
Elapsed time: 1 seconds
>> Done clustering of sample axolotl.
>> Redoing truncated PCA on sample lizard...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 4187
Number of edges: 172270

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8892
Number of communities: 11
Elapsed time: 0 seconds
>> Done clustering of sample lizard.
>> Redoing truncated PCA on sample paintedturtle...
found nearest neighbors.
revoke Seurat to compute SNN.
done.
done. returning result...
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 18664
Number of edges: 638406

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8901
Number of communities: 13
Elapsed time: 2 seconds
>> Done clustering of sample paintedturtle.
Finished clustering.
Obtained average profiles of clusters.
Start to calculate standardized similarities to clusters...
Doing z-transformation...
Done.
00:07:52 UMAP embedding parameters a = 0.9922 b = 1.112
00:07:52 Read 39266 rows and found 41 numeric columns
00:07:52 Using Annoy for neighbor search, n_neighbors = 30
00:07:52 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:07:58 Writing NN index file to temp file /tmp/RtmpyIf2G8/file2bdbd60b3d33d
00:07:58 Searching Annoy index using 1 thread, search_k = 3000
00:08:13 Annoy recall = 100%
00:08:14 Commencing smooth kNN distance calibration using 1 thread
00:08:18 Initializing from normalized Laplacian + noise
00:08:21 Commencing optimization for 200 epochs, with 1810424 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:09:11 Optimization finished

rPCA + Harmony, one2one ortholog

srat_rpca_harm_one_l = list()
for(n in names(srat_rpca_one_l)){
  print(n)
  # Run Harmony
  cell_integr = RunHarmony(srat_rpca_one_l[[n]], "species", tau = 30, 
                           plot_convergence = F, assay.use = "SCT")
  
  # Run UMAP on Harmony dimensions
  cell_integr = RunUMAP(cell_integr, reduction = "harmony", dims = 1:10)
  
  srat_rpca_harm_one_l[[n]] = cell_integr
}

CSS + Harmony, all ortholog

srat_css_harm_all_l = list()
for(n in names(srat_css_all_l)){
  print(n)
  # Run Harmony
  cell_integr = RunHarmony(srat_css_all_l[[n]], "species", tau = 30, reduction = "css",
                           dims.use = 1:ncol(Embeddings(srat_css_all_l[[n]],"css")),
                           plot_convergence = F, assay.use = "SCT")
  
  # Run UMAP on Harmony dimensions
  cell_integr = RunUMAP(cell_integr, reduction = "harmony", dims = 1:10)
  
  srat_css_harm_all_l[[n]] = cell_integr
}

CSS + Harmony, one2one ortholog

srat_css_harm_all_l = list()
for(n in names(srat_css_all_l)){
  print(n)
  # Run Harmony
  cell_integr = RunHarmony(srat_css_all_l[[n]], "species", tau = 30, reduction = "css",
                           dims.use = 1:ncol(Embeddings(srat_css_all_l[[n]],"css")),
                           plot_convergence = F, assay.use = "SCT")
  
  # Run UMAP on Harmony dimensions
  cell_integr = RunUMAP(cell_integr, reduction = "harmony", dims = 1:10)
  
  srat_css_harm_all_l[[n]] = cell_integr
}
[1] "all"
Harmony 1/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 2/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 3/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 4/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 5/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 6/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 7/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony converged after 7 iterations
Invalid name supplied, making object name syntactically valid. New object name is Seurat..ProjectDim.SCT.harmony; see ?make.names for more details on syntax validity00:11:22 UMAP embedding parameters a = 0.9922 b = 1.112
00:11:22 Read 39266 rows and found 10 numeric columns
00:11:22 Using Annoy for neighbor search, n_neighbors = 30
00:11:22 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:11:27 Writing NN index file to temp file /tmp/RtmpyIf2G8/file2bdbd3ea2902b
00:11:27 Searching Annoy index using 1 thread, search_k = 3000
00:11:43 Annoy recall = 100%
00:11:45 Commencing smooth kNN distance calibration using 1 thread
00:11:48 Initializing from normalized Laplacian + noise
00:11:50 Commencing optimization for 200 epochs, with 1651614 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:12:39 Optimization finished
[1] "allvar"
Quick-TRANSfer stage steps exceeded maximum (= 1963300)Harmony 1/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 2/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 3/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 4/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 5/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 6/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 7/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 8/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 9/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 10/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Invalid name supplied, making object name syntactically valid. New object name is Seurat..ProjectDim.SCT.harmony; see ?make.names for more details on syntax validity00:14:46 UMAP embedding parameters a = 0.9922 b = 1.112
00:14:46 Read 39266 rows and found 10 numeric columns
00:14:46 Using Annoy for neighbor search, n_neighbors = 30
00:14:46 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:14:51 Writing NN index file to temp file /tmp/RtmpyIf2G8/file2bdbd41e214cd
00:14:51 Searching Annoy index using 1 thread, search_k = 3000
00:15:06 Annoy recall = 100%
00:15:07 Commencing smooth kNN distance calibration using 1 thread
00:15:10 Initializing from normalized Laplacian + noise
00:15:12 Commencing optimization for 200 epochs, with 1645504 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:16:01 Optimization finished
[1] "commonvar"
Harmony 1/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 2/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 3/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 4/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 5/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 6/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 7/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony converged after 7 iterations
Invalid name supplied, making object name syntactically valid. New object name is Seurat..ProjectDim.SCT.harmony; see ?make.names for more details on syntax validity00:17:37 UMAP embedding parameters a = 0.9922 b = 1.112
00:17:37 Read 39266 rows and found 10 numeric columns
00:17:37 Using Annoy for neighbor search, n_neighbors = 30
00:17:37 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:17:42 Writing NN index file to temp file /tmp/RtmpyIf2G8/file2bdbd5e63e6fa
00:17:42 Searching Annoy index using 1 thread, search_k = 3000
00:17:58 Annoy recall = 100%
00:17:59 Commencing smooth kNN distance calibration using 1 thread
00:18:03 Initializing from normalized Laplacian + noise
00:18:05 Commencing optimization for 200 epochs, with 1670228 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:18:54 Optimization finished

Save lists

Save

srat_css_harm_one_l = list()
for(n in names(srat_css_one_l)){
  print(n)
  # Run Harmony
  cell_integr = RunHarmony(srat_css_one_l[[n]], "species", tau = 30, reduction = "css",
                           dims.use = 1:ncol(Embeddings(srat_css_one_l[[n]],"css")),
                           plot_convergence = F, assay.use = "SCT")
  
  # Run UMAP on Harmony dimensions
  cell_integr = RunUMAP(cell_integr, reduction = "harmony", dims = 1:10)
  
  srat_css_harm_one_l[[n]] = cell_integr
}
[1] "all"
Harmony 1/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 2/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 3/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 4/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 5/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony converged after 5 iterations
Invalid name supplied, making object name syntactically valid. New object name is Seurat..ProjectDim.SCT.harmony; see ?make.names for more details on syntax validity00:20:34 UMAP embedding parameters a = 0.9922 b = 1.112
00:20:34 Read 39266 rows and found 10 numeric columns
00:20:34 Using Annoy for neighbor search, n_neighbors = 30
00:20:34 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:20:40 Writing NN index file to temp file /tmp/RtmpyIf2G8/file2bdbd293b9c4c
00:20:40 Searching Annoy index using 1 thread, search_k = 3000
00:20:53 Annoy recall = 100%
00:20:55 Commencing smooth kNN distance calibration using 1 thread
00:20:58 Initializing from normalized Laplacian + noise
00:21:00 Commencing optimization for 200 epochs, with 1654888 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:21:49 Optimization finished
[1] "allvar"
Harmony 1/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 2/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 3/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 4/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 5/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 6/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 7/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 8/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 9/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony converged after 9 iterations
Invalid name supplied, making object name syntactically valid. New object name is Seurat..ProjectDim.SCT.harmony; see ?make.names for more details on syntax validity00:23:51 UMAP embedding parameters a = 0.9922 b = 1.112
00:23:51 Read 39266 rows and found 10 numeric columns
00:23:51 Using Annoy for neighbor search, n_neighbors = 30
00:23:51 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:23:56 Writing NN index file to temp file /tmp/RtmpyIf2G8/file2bdbd4c0ca239
00:23:56 Searching Annoy index using 1 thread, search_k = 3000
00:24:10 Annoy recall = 100%
00:24:11 Commencing smooth kNN distance calibration using 1 thread
00:24:14 Initializing from normalized Laplacian + noise
00:24:16 Commencing optimization for 200 epochs, with 1651456 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:25:05 Optimization finished
[1] "commonvar"
did not converge in 25 iterationsHarmony 1/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 2/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 3/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 4/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 5/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony converged after 5 iterations
Invalid name supplied, making object name syntactically valid. New object name is Seurat..ProjectDim.SCT.harmony; see ?make.names for more details on syntax validity00:26:31 UMAP embedding parameters a = 0.9922 b = 1.112
00:26:31 Read 39266 rows and found 10 numeric columns
00:26:31 Using Annoy for neighbor search, n_neighbors = 30
00:26:31 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:26:36 Writing NN index file to temp file /tmp/RtmpyIf2G8/file2bdbd88888be
00:26:36 Searching Annoy index using 1 thread, search_k = 3000
00:26:51 Annoy recall = 100%
00:26:52 Commencing smooth kNN distance calibration using 1 thread
00:26:55 Initializing from normalized Laplacian + noise
00:26:57 Commencing optimization for 200 epochs, with 1660784 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
00:27:46 Optimization finished

Plots for all genes

#saveRDS(srat_rpca_all_l, file = "./data/integration/srat_rpca_all_l.RDS")
#saveRDS(srat_rpca_one_l, file = "./data/integration/srat_rpca_one_l.RDS")

#saveRDS(srat_harm_all_l, file = "./data/integration/srat_harm_all_l.RDS")
#saveRDS(srat_harm_one_l, file = "./data/integration/srat_harm_one_l.RDS")

saveRDS(srat_css_all_l, file = "./data/integration/srat_css_all_l.RDS")
saveRDS(srat_css_one_l, file = "./data/integration/srat_css_one_l.RDS")

#saveRDS(srat_rpca_harm_all_l, file = "./data/integration/srat_rpca_harm_all_l.RDS")
#saveRDS(srat_rpca_harm_one_l, file = "./data/integration/srat_rpca_harm_one_l.RDS")

saveRDS(srat_css_harm_all_l, file = "./data/integration/srat_css_harm_all_l.RDS")
saveRDS(srat_css_harm_one_l, file = "./data/integration/srat_css_harm_one_l.RDS")

Plots for one2one genes

for(n in names(srat_rpca_all_l)){
  plt1 = DimPlot(srat_rpca_all_l[[n]], reduction = "umap", group.by = "species")+
    labs(title = paste0("rPCA, all orthologs, ", n))+
  DimPlot(srat_rpca_all_l[[n]], reduction = "umap", group.by = "classes")+
    labs(title = paste0("rPCA, all orthologs, ", n))
  print(plt1)
  
  plt2 = DimPlot(srat_css_all_l[[n]], reduction = "umap_css", group.by = "species")+
    labs(title = paste0("CSS, all orthologs, ", n))+
  DimPlot(srat_css_all_l[[n]], reduction = "umap_css", group.by = "classes")+
    labs(title = paste0("CSS, all orthologs, ", n))
  print(plt2)
  
  plt3 = DimPlot(srat_harm_all_l[[n]], reduction = "umap", group.by = "species")+
    labs(title = paste0("Harmony, all orthologs, ", n))+
  DimPlot(srat_harm_all_l[[n]], reduction = "umap", group.by = "classes")+
    labs(title = paste0("Harmony, all orthologs, ", n))
  print(plt3)
  
  plt4 = DimPlot(srat_rpca_harm_all_l[[n]], reduction = "umap", group.by = "species")+
    labs(title = paste0("rPCA+Harmony, all orthologs, ", n))+
  DimPlot(srat_rpca_harm_all_l[[n]], reduction = "umap", group.by = "classes")+
    labs(title = paste0("rPCA+Harmony, all orthologs, ", n))
  print(plt4)
  
  plt5 = DimPlot(srat_css_harm_all_l[[n]], reduction = "umap", group.by = "species")+
    labs(title = paste0("CSS+Harmony, all orthologs, ", n))+
  DimPlot(srat_css_harm_all_l[[n]], reduction = "umap", group.by = "classes")+
    labs(title = paste0("CSS+Harmony, all orthologs, ", n))
  print(plt5)
}

LS0tCnRpdGxlOiAiQ3Jvc3Mgc3BlY2llcyBjb3JyZWxhdGlvbiAtIHBhaXJ3aXNlIGdlbmVzICh1cGRhdGVkIG9ydGhvbG9neSkiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCk5vdGVib29rIGZvciBjZWxsIHR5cGUgaWRlbnRpdHkgY29ycmVsYXRpb25zIHVzaW5nIHBhaXJ3aXNlIGdlbmVzLiBTdWJzZXR0aW5nIHdpbGwgYmUgbmVlZGVkIHNpbmNlIGZvciBzb21lIG9mIHRoZSBzcGVjaWVzIHdlIG9ubHkgdXNlZCB0aGUgZmlyc3QgY2VsbCB0eXBlIG5hbWUgKHdoaWNoIGlzIHdoYXQgd2UncmUgbW9yZSBpbnRlcmVzdGVkIGluKS4KCgoKIyBHZW5lcmFsIFNldHVwClNldHVwIGNodW5rCgpgYGB7ciwgc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcud2lkdGggPSA4KQprbml0cjo6b3B0c19rbml0JHNldChyb290LmRpciA9IG5vcm1hbGl6ZVBhdGgoIi4uIikpCmtuaXRyOjpvcHRzX2tuaXQkZ2V0KCJyb290LmRpciIpCmBgYAoKU2V0dXAgcmV0aWN1bGF0ZQoKYGBge3J9CmxpYnJhcnkocmV0aWN1bGF0ZSkKa25pdHI6OmtuaXRfZW5naW5lcyRzZXQocHl0aG9uID0gcmV0aWN1bGF0ZTo6ZW5nX3B5dGhvbikKcHlfYXZhaWxhYmxlKGluaXRpYWxpemUgPSBGQUxTRSkKdXNlX3B5dGhvbihTeXMud2hpY2goInB5dGhvbiIpKQpweV9jb25maWcoKQpgYGAKCkxvYWQgbGlicmFyaWVzCgpgYGB7cn0KbGlicmFyeShTZXVyYXQpCmxpYnJhcnkoc2ltc3BlYykKbGlicmFyeShoYXJtb255KQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHV3b3QpCmBgYAoKCgojIERhdGEKTG9hZCBkYXRhc2V0cwoKYGBge3J9CmxpemFyZF9hbGwgPSByZWFkUkRTKCJkYXRhL2V4cHJlc3Npb24vbGl6YXJkX2FsbF92My5SRFMiKQp0dXJ0bGVfYWxsID0gcmVhZFJEUygiZGF0YS9leHByZXNzaW9uL3R1cnRsZV9hbGxfdjMuUkRTIikKYXhvbG90bF9hbGwgPSByZWFkUkRTKGZpbGUgPSAiZGF0YS9leHByZXNzaW9uL2F4b2xvdGwvcGFsbGl1bXJlczA3X2hhcm1vbnkuUkRTIikKYGBgCgpMb2FkIG1ldGFkYXRhcwoKYGBge3J9CmxpemFyZF9tZXRhID0gcmVhZC5jc3YoImRhdGEvYW5ub3RhdGlvbnMvbGl6YXJkX2FsbF91bWV0YS5jc3YiLCBoZWFkZXIgPSBULCByb3cubmFtZXMgPSAxKQp0dXJ0bGVfbWV0YSA9IHJlYWQuY3N2KCJkYXRhL2Fubm90YXRpb25zL3R1cnRsZV9hbGxfdW1ldGEuY3N2IiwgaGVhZGVyID0gVCwgcm93Lm5hbWVzID0gMSkKYXhvbG90bF9tZXRhID0gcmVhZC5jc3YoImRhdGEvYW5ub3RhdGlvbnMvYXhvbG90bF9hbGxfdW1ldGEuY3N2IiwgaGVhZGVyID0gVCwgcm93Lm5hbWVzID0gMSkKYGBgCgpBZGQgbWV0YWRhdGEKCmBgYHtyfQpsaXphcmRfYWxsID0gQWRkTWV0YURhdGEobGl6YXJkX2FsbCwgbWV0YWRhdGEgPSBsaXphcmRfbWV0YSkKdHVydGxlX2FsbCA9IEFkZE1ldGFEYXRhKHR1cnRsZV9hbGwsIG1ldGFkYXRhID0gdHVydGxlX21ldGEpCmF4b2xvdGxfYWxsID0gQWRkTWV0YURhdGEoYXhvbG90bF9hbGwsIG1ldGFkYXRhID0gYXhvbG90bF9tZXRhKQpgYGAKCkZpbHRlciBkYXRhIChkb3VibGV0cyBhbmQgb2RkIGNlbGxzKQoKYGBge3J9CnR1cnRsZV9hbGwgPSB0dXJ0bGVfYWxsWyx0dXJ0bGVfYWxsJGNsYXNzZXMhPSJkb3VibGV0cyJdCmF4b2xvdGxfYWxsID0gYXhvbG90bF9hbGxbLCFheG9sb3RsX2FsbCRjZWxsY2x1c3RlcnMgJWluJSBjKCJHQUJBZXJnaWMgbmV1cm9uIiwgIkVUVjErIG5ldXJvbiIsICJuZXVyb24iKV0KYGBgCgpQdXQgU2V1cmF0cyBpbiBsaXN0CgpgYGB7cn0Kc3JhdF9saXN0ID0gbGlzdCgicGFpbnRlZHR1cnRsZSIgPSB0dXJ0bGVfYWxsLCAiYXhvbG90bCIgPSBheG9sb3RsX2FsbCwgImxpemFyZCIgPSBsaXphcmRfYWxsKQpgYGAKCgoKIyBPcnRob2xvZyBtYXRjaGluZwpMb2FkIG5lY2Vzc2FyeSBvcnRob2xvZ3kgZGF0YQoKYGBge3J9Cm9ydF9hbHRfZW5zX2xpc3QgPSByZWFkUkRTKGZpbGUgPSAiZGF0YS9lZ2dOT0cvb3J0X2FsdF9lbnNfbGlzdC5SRFMiKQpvcnRfYWx0X2VnZ19saXN0ID0gcmVhZFJEUyhmaWxlID0gImRhdGEvZWdnTk9HL29ydF9hbHRfZWdnX2xpc3QuUkRTIikKCm9ydF9saXN0X3VzZSA9IGMob3J0X2FsdF9lbnNfbGlzdCwgCiAgICAgICAgICAgICAgICAgb3J0X2FsdF9lZ2dfbGlzdFt3aGljaChncmVwbCgiYXhvbG90bCIsIG5hbWVzKG9ydF9hbHRfZWdnX2xpc3QpKSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCJsaXphcmQiLCBuYW1lcyhvcnRfYWx0X2VnZ19saXN0KSkpXSkKYmZtYXRzID0gb3J0X2FsdF9lZ2dfbGlzdFt3aGljaChncmVwbCgiemVicmFmaW5jaCIsIG5hbWVzKG9ydF9hbHRfZWdnX2xpc3QpKSldCm5hbWVzKGJmbWF0cykgPSBnc3ViKCJ6ZWJyYWZpbmNoIiwgImJlbmdhbGVzZWZpbmNoIiwgbmFtZXMoYmZtYXRzKSkKb3J0X2xpc3RfdXNlID0gYyhvcnRfbGlzdF91c2UsIGJmbWF0cykKYGBgCgpGdW5jdGlvbiBmb3Igb3J0aG9sb2cgbWF0Y2hpbmcKCmBgYHtyfQojIGdldCBvcnRob2xvZ3MgZm9yIGFsbCBzcGVjaWVzIHBhaXJzCm9ydE1hdGNoID0gZnVuY3Rpb24ob3J0X2wsIHNwX3ZlYywgb3J0X3Njb3BlID0gIm9ydGhvbG9nX29uZTJvbmUiKXsKICBzcF9wX21hdCA9IGNvbWJuKHNwX3ZlYywgMikKICBmb3IoaSBpbiAxOm5jb2woc3BfcF9tYXQpKXsKICAgIHNwX3BhaXIgPSBzcF9wX21hdFssaV0KICAgIG9ydF90YWIgPSBvcnRfbFtbcGFzdGUwKHNwX3BhaXIsIGNvbGxhcHNlID0gIi52cy4iKV1dCiAgICBpZighaXMubnVsbChvcnRfc2NvcGUpKXsKICAgICAgb3J0X3RhYiA9IG9ydF90YWJbb3J0X3RhYiRob21vbG9neS50eXBlPT1vcnRfc2NvcGUsXQogICAgfQoKICAgIGNvbG5hbWVzKG9ydF90YWIpID0gZ3N1YigiZ2VuZW5hbWUiLCAiIiwgY29sbmFtZXMob3J0X3RhYikpCiAgICBpZihpPT0xKXsKICAgICAgb3J0X2FsbCA9IHVuaXF1ZShvcnRfdGFiWyxjKDIsNCldKQogICAgfSBlbHNlewogICAgICBvcnRfYWxsID0gdW5pcXVlKG1lcmdlKG9ydF9hbGwsIHVuaXF1ZShvcnRfdGFiWyxjKDIsNCldKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBpbnRlcnNlY3QoY29sbmFtZXMob3J0X2FsbCksIGNvbG5hbWVzKG9ydF90YWIpKSkpCiAgICB9CiAgfQogIAogIHJldHVybihvcnRfYWxsKQp9CmBgYAoKRnVuY3Rpb24gZm9yIHN1YnNldHRpbmcgU2V1cmF0cwoKYGBge3J9CnNldXJhdE9ydGhvbG9ncyA9IGZ1bmN0aW9uKHNfbCwgb19hbGwpewogICMgb25seSBvcnRob2xvZ3MgcHJlc2VudCBpbiB0aGUgU2V1cmF0IG9iamVjdHMKICBmb3Ioc3AgaW4gbmFtZXMoc19sKSl7CiAgICBvX2FsbCA9IG9fYWxsW29fYWxsWyxzcF0gJWluJSByb3duYW1lcyhzX2xbW3NwXV0pLF0KICB9CiAgCiAgIyBnZXQgYSB1bmlxdWUgbmFtZSBmb3IgdGhlIGdlbmVzCiAgYWxsZyA9IHVubGlzdChvX2FsbCkKICBqb2ludG5hbWVzID0gYygpCiAgcmVwX24gPSBsaXN0KCkKICBmb3IoaSBpbiAxOm5yb3cob19hbGwpKXsKICAgIG5uYW1lID0gdW5saXN0KGxhcHBseShvX2FsbFtpLF0sIGZ1bmN0aW9uKHgpIHN1bShhbGxnPT14KSkpCiAgICBnID0gdW5saXN0KG9fYWxsW2ksbmFtZXMobm5hbWVbbm5hbWU9PTFdKV0pCiAgICAjIGlmIHRoZXJlIGFyZSBhY2NlcHRhYmxlIHVuaXF1ZSBuYW1lcwogICAgaWYoYW55KG5uYW1lPT0xKSAmICghaXMubnVsbChnKSAmICFhbGwoZ3JlcGwoIi4uIiwgZywgZml4ZWQgPSBUKSkpKXsgIyBubyB3ZWlyZCBheG9sb2x0IGFubm90CiAgICAgIGcgPSBnWyFncmVwbCgiLi4iLCBnLCBmaXhlZCA9IFQpXSAjIG5vIHdlaXJkIGF4b2xvbHQgYW5ub3QKICAgICAgZyA9IGMoZ1shZ3JlcGwoIkxPQyIsIGcpXSwgZ1tncmVwbCgiTE9DIiwgZyldKVsxXSAjcHJpb3JpdGl6ZSBub24tTE9DCiAgICAgIGpvaW50bmFtZXMgPSBjKGpvaW50bmFtZXMsIGcpCiAgICAgIHJlcF9uW1tnXV0gPSAxCiAgICB9IGVsc2V7ICMgd2UnbGwgYWRkIGEgbnVtYmVyIHRvIHRob3NlIG5hbWVzCiAgICAgIGcgPSB1bmxpc3Qob19hbGxbaSxdKQogICAgICBnID0gZ1shZ3JlcGwoIi4uIiwgZywgZml4ZWQgPSBUKV0gIyBubyB3ZWlyZCBheG9sb2x0IGFubm90CiAgICAgIGcgPSBjKGdbIWdyZXBsKCJMT0MiLCBnKV0sIGdbZ3JlcGwoIkxPQyIsIGcpXSlbMV0gI3ByaW9yaXRpemUgbm9uLUxPQwogICAgICBpZihnICVpbiUgbmFtZXMocmVwX24pKXsKICAgICAgICBnbiA9IHJlcF9uW1tnXV0KICAgICAgICByZXBfbltbZ11dID0gZ24rMQogICAgICAgIGpvaW50bmFtZXMgPSBjKGpvaW50bmFtZXMsIHBhc3RlMChnLCAiLSIsIGduKzEpKQogICAgICB9IGVsc2V7CiAgICAgICAgcmVwX25bW2ddXSA9IDEKICAgICAgICBqb2ludG5hbWVzID0gYyhqb2ludG5hbWVzLCBwYXN0ZTAoZywgIi0iLCAxKSkKICAgICAgfQogICAgfQogIH0KICAKICAjIGZpbHRlciB0aGUgU2V1cmF0cyBieSB0aGUgb3J0aG9sb2dzCiAgIyMgdGhpcyByZXF1aXJlcyByZWRvaW5nIHRoZSBTZXVyYXQgd2l0aCBuZXcgbmFtZXMsIHNpbmNlIHNvbWUgZ2VuZXMgd2lsbCBiZSBkdXBsaWNhdGVkCiAgZm9yKHNwIGluIG5hbWVzKHNfbCkpewogICAgY250cyA9IHNfbFtbc3BdXUBhc3NheXMkUk5BQGNvdW50c1tvX2FsbFssc3BdLF0KICAgIHJvd25hbWVzKGNudHMpID0gam9pbnRuYW1lcwogICAgbSA9IHNfbFtbc3BdXUBtZXRhLmRhdGEKICAgIHNfbFtbc3BdXSA9IENyZWF0ZVNldXJhdE9iamVjdChjbnRzLCBwcm9qZWN0ID0gc3AsIG1ldGEuZGF0YSA9IG0pCiAgfQogIAogIHJldHVybihzX2wpCn0KYGBgCgpHZXQgb3J0aG9sb2ctbWF0Y2hlZCBTZXVyYXRzCgpgYGB7cn0Kc3JhdF9vcnQgPSBzZXVyYXRPcnRob2xvZ3Moc3JhdF9saXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgb3J0TWF0Y2gob3J0X2xpc3RfdXNlLCBjKCJwYWludGVkdHVydGxlIiwgImF4b2xvdGwiLCAibGl6YXJkIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcnRfc2NvcGUgPSBOVUxMKSkKbGFwcGx5KHNyYXRfb3J0LCBkaW0pCgpzcmF0X29ydDEgPSBzZXVyYXRPcnRob2xvZ3Moc3JhdF9saXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ydE1hdGNoKG9ydF9saXN0X3VzZSwgYygicGFpbnRlZHR1cnRsZSIsICJheG9sb3RsIiwgImxpemFyZCIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ydF9zY29wZSA9ICJvcnRob2xvZ19vbmUyb25lIikpCmxhcHBseShzcmF0X29ydDEsIGRpbSkKYGBgCgoKCiMgSW50ZWdyYXRpb24KTm9ybWFsaXNlIGRhdGEKCmBgYHtyfQpmb3Ioc3AgaW4gbmFtZXMoc3JhdF9vcnQpKXsKICBwcmludChzcCkKICBzcmF0X29ydFtbc3BdXSA9IHN1cHByZXNzV2FybmluZ3MoU0NUcmFuc2Zvcm0oc3JhdF9vcnRbW3NwXV0sIGRvLmNvcnJlY3QudW1pID0gVCwgdmVyYm9zZSA9IEYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQudXNlID0gMSwgdmFycy50by5yZWdyZXNzID0gIm5Db3VudF9STkEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5mZWF0dXJlcy5ydi50aCA9IDEsIHJldHVybi5vbmx5LnZhci5nZW5lcyA9IEYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlLmZlYXR1cmVzLm4gPSBOVUxMKSkKICBzcmF0X29ydDFbW3NwXV0gPSBzdXBwcmVzc1dhcm5pbmdzKFNDVHJhbnNmb3JtKHNyYXRfb3J0MVtbc3BdXSwgZG8uY29ycmVjdC51bWkgPSBULCB2ZXJib3NlID0gRiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQudXNlID0gMSwgdmFycy50by5yZWdyZXNzID0gIm5Db3VudF9STkEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUuZmVhdHVyZXMucnYudGggPSAxLCByZXR1cm4ub25seS52YXIuZ2VuZXMgPSBGLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUuZmVhdHVyZXMubiA9IE5VTEwpKQp9CmBgYAoKU2V1cmF0cyB3aXRoIGFsbCBtZXJnZWQKCmBgYHtyfQpzcmF0X29ydF9hbGwgPSBSZWR1Y2UobWVyZ2UsIHNyYXRfb3J0KQpzcmF0X29ydF9hbGwgPSBBZGRNZXRhRGF0YShzcmF0X29ydF9hbGwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSA9IHVubGlzdChsYXBwbHkobmFtZXMoc3JhdF9vcnQpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHJlcCh4LCBuY29sKHNyYXRfb3J0W1t4XV0pKSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wubmFtZSA9ICJzcGVjaWVzIikKCnNyYXRfb3J0MV9hbGwgPSBSZWR1Y2UobWVyZ2UsIHNyYXRfb3J0MSkKc3JhdF9vcnQxX2FsbCA9IEFkZE1ldGFEYXRhKHNyYXRfb3J0MV9hbGwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSA9IHVubGlzdChsYXBwbHkobmFtZXMoc3JhdF9vcnQxKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSByZXAoeCwgbmNvbChzcmF0X29ydDFbW3hdXSkpKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5uYW1lID0gInNwZWNpZXMiKQpgYGAKCgojIyBTZXVyYXQgclBDQQpJbnRlZ3JhdGlvbiB3aXRoIGFsbCBvcnRob2xvZwoKYGBge3J9CmZlYXRfbGlzdCA9IGxpc3QoImFsbCIgPSByb3duYW1lcyhzcmF0X29ydF9hbGxAYXNzYXlzJFNDVEBzY2FsZS5kYXRhKSwgCiAgICAgICAgICAgICAgICAgImFsbHZhciIgPSB1bmlxdWUodW5saXN0KGxhcHBseShzcmF0X29ydCwgVmFyaWFibGVGZWF0dXJlcykpKSwgCiAgICAgICAgICAgICAgICAgImNvbW1vbnZhciIgPSBSZWR1Y2UoaW50ZXJzZWN0LCBsYXBwbHkoc3JhdF9vcnQsIFZhcmlhYmxlRmVhdHVyZXMpKSkKdmFyaW5kYXQgPSBsYXBwbHkoc3JhdF9vcnQsIGZ1bmN0aW9uKHgpIGZlYXRfbGlzdCRhbGx2YXIgJWluJSByb3duYW1lcyh4KSkKZmVhdF9saXN0JGFsbHZhciA9IGZlYXRfbGlzdCRhbGx2YXJbcm93U3VtcyhSZWR1Y2UoY2JpbmQsIHZhcmluZGF0KSk9PWxlbmd0aChzcmF0X29ydCldCnNyYXRfcnBjYV9hbGxfbCA9IGxpc3QoKQpmb3IobiBpbiBuYW1lcyhmZWF0X2xpc3QpKXsKICBwcmludChuKQogIGludGVncl9mZWF0ID0gZmVhdF9saXN0W1tuXV0KICAKICAjIGNhbGN1bGF0ZSBwb3NzaWJsZSBtaXNzaW5nIFBlYXJzb24gcmVzaWR1YWxzIGZvciBTQ1RyYW5zZm9ybQogIHNyYXRfb3J0X2ludCA9IFByZXBTQ1RJbnRlZ3JhdGlvbihzcmF0X29ydCwgYW5jaG9yLmZlYXR1cmVzID0gaW50ZWdyX2ZlYXQsIHZlcmJvc2UgPSBUKQogIAogIHNyYXRfb3J0X2ludCA8LSBsYXBwbHkoWCA9IHNyYXRfb3J0X2ludCwgRlVOID0gZnVuY3Rpb24oeCkgewogICAgeCA8LSBTY2FsZURhdGEoeCwgZmVhdHVyZXMgPSBpbnRlZ3JfZmVhdCwgdmVyYm9zZSA9IEZBTFNFKQogICAgeCA8LSBSdW5QQ0EoeCwgZmVhdHVyZXMgPSBpbnRlZ3JfZmVhdCwgdmVyYm9zZSA9IEZBTFNFKQogIH0pCiAgCiAgIyBmaW5kaW5nIHRoZSBhbmNob3JzIGZvciBpbnRlZ3JhdGlvbgogIGFsbF9jZWxsX2FuY2hvcnMgPSBGaW5kSW50ZWdyYXRpb25BbmNob3JzKHNyYXRfb3J0X2ludCwgbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiU0NUIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yLmZlYXR1cmVzID0gaW50ZWdyX2ZlYXQsIHJlZHVjdGlvbiA9ICJycGNhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NheSA9IHJlcCgiU0NUIiwgbGVuZ3RoKHNyYXRfb3J0X2ludCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW1zID0gMTo1MCwgdmVyYm9zZSA9IFQpCiAgCiAgIyBhY3R1YWwgZGF0YSBpbnRlZ3JhdGlvbgogIGFsbGdlbmVzID0gcm93bmFtZXMoc3JhdF9vcnRfaW50W1sxXV1AYXNzYXlzJFJOQUBjb3VudHMpCiAgYWxsX2NlbGxfaW50ZWdyID0gSW50ZWdyYXRlRGF0YShhbGxfY2VsbF9hbmNob3JzLCBub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJTQ1QiLCBkaW1zID0gMTo1MCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBULCBmZWF0dXJlcy50by5pbnRlZ3JhdGUgPSBhbGxnZW5lcykKICAKICAjIHJ1biBQQ0EgYW5kIFVNQVAgdG8gc2VlIGhvdyBpdCBsb29rcwogIGFsbF9jZWxsX2ludGVnciA9IFJ1blBDQShhbGxfY2VsbF9pbnRlZ3IsIHZlcmJvc2UgPSBGKQogIGFsbF9jZWxsX2ludGVnciA9IFJ1blVNQVAoYWxsX2NlbGxfaW50ZWdyLCBkaW1zID0gMTozMCkKICAKICBhbGxfY2VsbF9pbnRlZ3IgPSBBZGRNZXRhRGF0YShhbGxfY2VsbF9pbnRlZ3IsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhID0gdW5saXN0KGxhcHBseShuYW1lcyhzcmF0X29ydCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSByZXAoeCwgbmNvbChzcmF0X29ydFtbeF1dKSkpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wubmFtZSA9ICJzcGVjaWVzIikKICBzcmF0X3JwY2FfYWxsX2xbW25dXSA9IGFsbF9jZWxsX2ludGVncgp9CmBgYAoKSW50ZWdyYXRpb24gd2l0aCBvbmUyb25lIG9ydGhvbG9nCgpgYGB7cn0KZmVhdF9saXN0ID0gbGlzdCgiYWxsIiA9IHJvd25hbWVzKHNyYXRfb3J0MV9hbGxAYXNzYXlzJFNDVEBzY2FsZS5kYXRhKSwgCiAgICAgICAgICAgICAgICAgImFsbHZhciIgPSB1bmlxdWUodW5saXN0KGxhcHBseShzcmF0X29ydDEsIFZhcmlhYmxlRmVhdHVyZXMpKSksIAogICAgICAgICAgICAgICAgICJjb21tb252YXIiID0gUmVkdWNlKGludGVyc2VjdCwgbGFwcGx5KHNyYXRfb3J0MSwgVmFyaWFibGVGZWF0dXJlcykpKQp2YXJpbmRhdCA9IGxhcHBseShzcmF0X29ydDEsIGZ1bmN0aW9uKHgpIGZlYXRfbGlzdCRhbGx2YXIgJWluJSByb3duYW1lcyh4KSkKZmVhdF9saXN0JGFsbHZhciA9IGZlYXRfbGlzdCRhbGx2YXJbcm93U3VtcyhSZWR1Y2UoY2JpbmQsIHZhcmluZGF0KSk9PWxlbmd0aChzcmF0X29ydDEpXQpzcmF0X3JwY2Ffb25lX2wgPSBsaXN0KCkKZm9yKG4gaW4gbmFtZXMoZmVhdF9saXN0KSl7CiAgcHJpbnQobikKICBpbnRlZ3JfZmVhdCA9IGZlYXRfbGlzdFtbbl1dCiAgCiAgIyBjYWxjdWxhdGUgcG9zc2libGUgbWlzc2luZyBQZWFyc29uIHJlc2lkdWFscyBmb3IgU0NUcmFuc2Zvcm0KICBzcmF0X29ydDFfaW50ID0gUHJlcFNDVEludGVncmF0aW9uKHNyYXRfb3J0MSwgYW5jaG9yLmZlYXR1cmVzID0gaW50ZWdyX2ZlYXQsIHZlcmJvc2UgPSBUKQogIAogIHNyYXRfb3J0MV9pbnQgPC0gbGFwcGx5KFggPSBzcmF0X29ydDFfaW50LCBGVU4gPSBmdW5jdGlvbih4KSB7CiAgICB4IDwtIFNjYWxlRGF0YSh4LCBmZWF0dXJlcyA9IGludGVncl9mZWF0LCB2ZXJib3NlID0gRkFMU0UpCiAgICB4IDwtIFJ1blBDQSh4LCBmZWF0dXJlcyA9IGludGVncl9mZWF0LCB2ZXJib3NlID0gRkFMU0UpCiAgfSkKICAKICAjIGZpbmRpbmcgdGhlIGFuY2hvcnMgZm9yIGludGVncmF0aW9uCiAgYWxsX2NlbGxfYW5jaG9ycyA9IEZpbmRJbnRlZ3JhdGlvbkFuY2hvcnMoc3JhdF9vcnQxX2ludCwgbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiU0NUIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yLmZlYXR1cmVzID0gaW50ZWdyX2ZlYXQsIHJlZHVjdGlvbiA9ICJycGNhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NheSA9IHJlcCgiU0NUIiwgbGVuZ3RoKHNyYXRfb3J0MV9pbnQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltcyA9IDE6NTAsIHZlcmJvc2UgPSBUKQogIAogICMgYWN0dWFsIGRhdGEgaW50ZWdyYXRpb24KICBhbGxnZW5lcyA9IHJvd25hbWVzKHNyYXRfb3J0MV9pbnRbWzFdXUBhc3NheXMkUk5BQGNvdW50cykKICBhbGxfY2VsbF9pbnRlZ3IgPSBJbnRlZ3JhdGVEYXRhKGFsbF9jZWxsX2FuY2hvcnMsIG5vcm1hbGl6YXRpb24ubWV0aG9kID0gIlNDVCIsIGRpbXMgPSAxOjUwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IFQsIGZlYXR1cmVzLnRvLmludGVncmF0ZSA9IGFsbGdlbmVzKQogIAogICMgcnVuIFBDQSBhbmQgVU1BUCB0byBzZWUgaG93IGl0IGxvb2tzCiAgYWxsX2NlbGxfaW50ZWdyID0gUnVuUENBKGFsbF9jZWxsX2ludGVnciwgdmVyYm9zZSA9IEYpCiAgYWxsX2NlbGxfaW50ZWdyID0gUnVuVU1BUChhbGxfY2VsbF9pbnRlZ3IsIGRpbXMgPSAxOjMwKQogIAogIGFsbF9jZWxsX2ludGVnciA9IEFkZE1ldGFEYXRhKGFsbF9jZWxsX2ludGVnciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGEgPSB1bmxpc3QobGFwcGx5KG5hbWVzKHNyYXRfb3J0MSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSByZXAoeCwgbmNvbChzcmF0X29ydDFbW3hdXSkpKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLm5hbWUgPSAic3BlY2llcyIpCiAgc3JhdF9ycGNhX29uZV9sW1tuXV0gPSBhbGxfY2VsbF9pbnRlZ3IKfQpgYGAKCgojIyBIYXJtb255CkludGVncmF0aW9uIHdpdGggYWxsIG9ydGhvbG9nCgpgYGB7cn0KZmVhdF9saXN0ID0gbGlzdCgiYWxsIiA9IHJvd25hbWVzKHNyYXRfb3J0X2FsbEBhc3NheXMkU0NUQHNjYWxlLmRhdGEpLCAKICAgICAgICAgICAgICAgICAiYWxsdmFyIiA9IHVuaXF1ZSh1bmxpc3QobGFwcGx5KHNyYXRfb3J0LCBWYXJpYWJsZUZlYXR1cmVzKSkpLCAKICAgICAgICAgICAgICAgICAiY29tbW9udmFyIiA9IFJlZHVjZShpbnRlcnNlY3QsIGxhcHBseShzcmF0X29ydCwgVmFyaWFibGVGZWF0dXJlcykpKQp2YXJpbmRhdCA9IGxhcHBseShzcmF0X29ydCwgZnVuY3Rpb24oeCkgZmVhdF9saXN0JGFsbHZhciAlaW4lIHJvd25hbWVzKHgpKQpmZWF0X2xpc3QkYWxsdmFyID0gZmVhdF9saXN0JGFsbHZhcltyb3dTdW1zKFJlZHVjZShjYmluZCwgdmFyaW5kYXQpKT09bGVuZ3RoKHNyYXRfb3J0KV0Kc3JhdF9oYXJtX2FsbF9sID0gbGlzdCgpCmZvcihuIGluIG5hbWVzKGZlYXRfbGlzdCkpewogIHByaW50KG4pCiAgIyBSZW5vcm1hbGlzZQogIGludGVncl9mZWF0ID0gZmVhdF9saXN0W1tuXV0KICBWYXJpYWJsZUZlYXR1cmVzKHNyYXRfb3J0X2FsbCkgPSBpbnRlZ3JfZmVhdAogIHNyYXRfb3J0X2FsbF9pbnQgPSBTY2FsZURhdGEoc3JhdF9vcnRfYWxsLCBmZWF0dXJlcyA9IGludGVncl9mZWF0LCB1c2UudW1pID0gVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvLnNjYWxlID0gRiwgdmVyYm9zZSA9IEZBTFNFKQogIHNyYXRfb3J0X2FsbF9pbnQgPSBSdW5QQ0Eoc3JhdF9vcnRfYWxsX2ludCwgdmVyYm9zZSA9IEZBTFNFLCBhc3NheSA9ICJTQ1QiLCBucGNzID0gNTAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcyA9IGludGVncl9mZWF0KQogIAogICMgUnVuIEhhcm1vbnkKICBzcmF0X29ydF9hbGxfaW50ID0gUnVuSGFybW9ueShzcmF0X29ydF9hbGxfaW50LCAic3BlY2llcyIsIHRhdSA9IDMwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90X2NvbnZlcmdlbmNlID0gRiwgYXNzYXkudXNlID0gIlNDVCIpCiAgCiAgIyBSdW4gVU1BUCBvbiBIYXJtb255IGRpbWVuc2lvbnMKICBzcmF0X29ydF9hbGxfaW50ID0gUnVuVU1BUChzcmF0X29ydF9hbGxfaW50LCByZWR1Y3Rpb24gPSAiaGFybW9ueSIsIGRpbXMgPSAxOjEwKQogIAogIHNyYXRfaGFybV9hbGxfbFtbbl1dID0gc3JhdF9vcnRfYWxsX2ludAp9CmBgYAoKSW50ZWdyYXRpb24gd2l0aCBvbmUyb25lIG9ydGhvbG9nCgpgYGB7cn0KZmVhdF9saXN0ID0gbGlzdCgiYWxsIiA9IHJvd25hbWVzKHNyYXRfb3J0MV9hbGxAYXNzYXlzJFNDVEBzY2FsZS5kYXRhKSwgCiAgICAgICAgICAgICAgICAgImFsbHZhciIgPSB1bmlxdWUodW5saXN0KGxhcHBseShzcmF0X29ydDEsIFZhcmlhYmxlRmVhdHVyZXMpKSksIAogICAgICAgICAgICAgICAgICJjb21tb252YXIiID0gUmVkdWNlKGludGVyc2VjdCwgbGFwcGx5KHNyYXRfb3J0MSwgVmFyaWFibGVGZWF0dXJlcykpKQp2YXJpbmRhdCA9IGxhcHBseShzcmF0X29ydDEsIGZ1bmN0aW9uKHgpIGZlYXRfbGlzdCRhbGx2YXIgJWluJSByb3duYW1lcyh4KSkKZmVhdF9saXN0JGFsbHZhciA9IGZlYXRfbGlzdCRhbGx2YXJbcm93U3VtcyhSZWR1Y2UoY2JpbmQsIHZhcmluZGF0KSk9PWxlbmd0aChzcmF0X29ydDEpXQpzcmF0X2hhcm1fb25lX2wgPSBsaXN0KCkKZm9yKG4gaW4gbmFtZXMoZmVhdF9saXN0KSl7CiAgcHJpbnQobikKICAjIFJlbm9ybWFsaXNlCiAgaW50ZWdyX2ZlYXQgPSBmZWF0X2xpc3RbW25dXQogIFZhcmlhYmxlRmVhdHVyZXMoc3JhdF9vcnQxX2FsbCkgPSBpbnRlZ3JfZmVhdAogIHNyYXRfb3J0MV9hbGxfaW50ID0gU2NhbGVEYXRhKHNyYXRfb3J0MV9hbGwsIGZlYXR1cmVzID0gaW50ZWdyX2ZlYXQsIHVzZS51bWkgPSBULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG8uc2NhbGUgPSBGLCB2ZXJib3NlID0gRkFMU0UpCiAgc3JhdF9vcnQxX2FsbF9pbnQgPSBSdW5QQ0Eoc3JhdF9vcnQxX2FsbF9pbnQsIHZlcmJvc2UgPSBGQUxTRSwgYXNzYXkgPSAiU0NUIiwgbnBjcyA9IDUwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXMgPSBpbnRlZ3JfZmVhdCkKICAKICAjIFJ1biBIYXJtb255CiAgc3JhdF9vcnQxX2FsbF9pbnQgPSBSdW5IYXJtb255KHNyYXRfb3J0MV9hbGxfaW50LCAic3BlY2llcyIsIHRhdSA9IDMwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdF9jb252ZXJnZW5jZSA9IEYsIGFzc2F5LnVzZSA9ICJTQ1QiKQogIAogICMgUnVuIFVNQVAgb24gSGFybW9ueSBkaW1lbnNpb25zCiAgc3JhdF9vcnQxX2FsbF9pbnQgPSBSdW5VTUFQKHNyYXRfb3J0MV9hbGxfaW50LCByZWR1Y3Rpb24gPSAiaGFybW9ueSIsIGRpbXMgPSAxOjEwKQogIAogIHNyYXRfaGFybV9vbmVfbFtbbl1dID0gc3JhdF9vcnQxX2FsbF9pbnQKfQpgYGAKCgojIyBDU1MKSW50ZWdyYXRpb24gd2l0aCBhbGwgb3J0aG9sb2cKCmBgYHtyfQpmZWF0X2xpc3QgPSBsaXN0KCJhbGwiID0gcm93bmFtZXMoc3JhdF9vcnRfYWxsQGFzc2F5cyRTQ1RAc2NhbGUuZGF0YSksIAogICAgICAgICAgICAgICAgICJhbGx2YXIiID0gdW5pcXVlKHVubGlzdChsYXBwbHkoc3JhdF9vcnQsIFZhcmlhYmxlRmVhdHVyZXMpKSksIAogICAgICAgICAgICAgICAgICJjb21tb252YXIiID0gUmVkdWNlKGludGVyc2VjdCwgbGFwcGx5KHNyYXRfb3J0LCBWYXJpYWJsZUZlYXR1cmVzKSkpCnZhcmluZGF0ID0gbGFwcGx5KHNyYXRfb3J0LCBmdW5jdGlvbih4KSBmZWF0X2xpc3QkYWxsdmFyICVpbiUgcm93bmFtZXMoeCkpCmZlYXRfbGlzdCRhbGx2YXIgPSBmZWF0X2xpc3QkYWxsdmFyW3Jvd1N1bXMoUmVkdWNlKGNiaW5kLCB2YXJpbmRhdCkpPT1sZW5ndGgoc3JhdF9vcnQpXQpzcmF0X2Nzc19hbGxfbCA9IGxpc3QoKQpmb3IobiBpbiBuYW1lcyhmZWF0X2xpc3QpKXsKICBwcmludChuKQogIGludGVncl9mZWF0ID0gZmVhdF9saXN0W1tuXV0KICBWYXJpYWJsZUZlYXR1cmVzKHNyYXRfb3J0X2FsbCkgPSBpbnRlZ3JfZmVhdAogIHNyYXRfb3J0X2FsbF9pbnQgPSBTY2FsZURhdGEoc3JhdF9vcnRfYWxsLCBmZWF0dXJlcyA9IGludGVncl9mZWF0LCB1c2UudW1pID0gVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvLnNjYWxlID0gRiwgdmVyYm9zZSA9IEZBTFNFKQogIHNyYXRfb3J0X2FsbF9pbnQgPSBSdW5QQ0Eoc3JhdF9vcnRfYWxsX2ludCwgdmVyYm9zZSA9IEZBTFNFLCBhc3NheSA9ICJTQ1QiLCBucGNzID0gNTAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcyA9IGludGVncl9mZWF0KQogIAogICMgUnVuIENTUwogIHNyYXRfb3J0X2FsbF9pbnQgPSBjbHVzdGVyX3NpbV9zcGVjdHJ1bShzcmF0X29ydF9hbGxfaW50LCBsYWJlbF90YWc9InNwZWNpZXMiLCByZWRvX3BjYSA9IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW1zX3VzZSA9IDE6MzAsIHZhcl9nZW5lcyA9IGludGVncl9mZWF0KQogIAogICMgUnVuIFVNQVAgb24gQ1NTIGRpbWVuc2lvbnMKICBzcmF0X29ydF9hbGxfaW50ID0gUnVuVU1BUChzcmF0X29ydF9hbGxfaW50LCByZWR1Y3Rpb249ImNzcyIsIHJlZHVjdGlvbi5uYW1lPSJ1bWFwX2NzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltcyA9IDE6bmNvbChFbWJlZGRpbmdzKHNyYXRfb3J0X2FsbF9pbnQsImNzcyIpKSwgcmVkdWN0aW9uLmtleT0iVU1BUENTU18iKQogIHNyYXRfb3J0X2FsbF9pbnQgPSBTZXRJZGVudChzcmF0X29ydF9hbGxfaW50LCB2YWx1ZSA9ICJzcGVjaWVzIikKICAKICBzcmF0X2Nzc19hbGxfbFtbbl1dID0gc3JhdF9vcnRfYWxsX2ludAp9CmBgYAoKSW50ZWdyYXRpb24gd2l0aCBvbmUyb25lIG9ydGhvbG9nCgpgYGB7cn0KZmVhdF9saXN0ID0gbGlzdCgiYWxsIiA9IHJvd25hbWVzKHNyYXRfb3J0MV9hbGxAYXNzYXlzJFNDVEBzY2FsZS5kYXRhKSwgCiAgICAgICAgICAgICAgICAgImFsbHZhciIgPSB1bmlxdWUodW5saXN0KGxhcHBseShzcmF0X29ydDEsIFZhcmlhYmxlRmVhdHVyZXMpKSksIAogICAgICAgICAgICAgICAgICJjb21tb252YXIiID0gUmVkdWNlKGludGVyc2VjdCwgbGFwcGx5KHNyYXRfb3J0MSwgVmFyaWFibGVGZWF0dXJlcykpKQp2YXJpbmRhdCA9IGxhcHBseShzcmF0X29ydDEsIGZ1bmN0aW9uKHgpIGZlYXRfbGlzdCRhbGx2YXIgJWluJSByb3duYW1lcyh4KSkKZmVhdF9saXN0JGFsbHZhciA9IGZlYXRfbGlzdCRhbGx2YXJbcm93U3VtcyhSZWR1Y2UoY2JpbmQsIHZhcmluZGF0KSk9PWxlbmd0aChzcmF0X29ydDEpXQpzcmF0X2Nzc19vbmVfbCA9IGxpc3QoKQpmb3IobiBpbiBuYW1lcyhmZWF0X2xpc3QpKXsKICBwcmludChuKQogIGludGVncl9mZWF0ID0gZmVhdF9saXN0W1tuXV0KICBWYXJpYWJsZUZlYXR1cmVzKHNyYXRfb3J0MV9hbGwpID0gaW50ZWdyX2ZlYXQKICBzcmF0X29ydDFfYWxsX2ludCA9IFNjYWxlRGF0YShzcmF0X29ydDFfYWxsLCBmZWF0dXJlcyA9IGludGVncl9mZWF0LCB1c2UudW1pID0gVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvLnNjYWxlID0gRiwgdmVyYm9zZSA9IEZBTFNFKQogIHNyYXRfb3J0MV9hbGxfaW50ID0gUnVuUENBKHNyYXRfb3J0MV9hbGxfaW50LCB2ZXJib3NlID0gRkFMU0UsIGFzc2F5ID0gIlNDVCIsIG5wY3MgPSA1MCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzID0gaW50ZWdyX2ZlYXQpCiAgCiAgIyBSdW4gQ1NTCiAgc3JhdF9vcnQxX2FsbF9pbnQgPSBjbHVzdGVyX3NpbV9zcGVjdHJ1bShzcmF0X29ydDFfYWxsX2ludCwgbGFiZWxfdGFnPSJzcGVjaWVzIiwgcmVkb19wY2EgPSBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltc191c2UgPSAxOjMwLCB2YXJfZ2VuZXMgPSBpbnRlZ3JfZmVhdCkKICAKICAjIFJ1biBVTUFQIG9uIENTUyBkaW1lbnNpb25zCiAgc3JhdF9vcnQxX2FsbF9pbnQgPSBSdW5VTUFQKHNyYXRfb3J0MV9hbGxfaW50LCByZWR1Y3Rpb249ImNzcyIsIHJlZHVjdGlvbi5uYW1lPSJ1bWFwX2NzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltcyA9IDE6bmNvbChFbWJlZGRpbmdzKHNyYXRfb3J0MV9hbGxfaW50LCJjc3MiKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVkdWN0aW9uLmtleT0iVU1BUENTU18iKQogIHNyYXRfb3J0MV9hbGxfaW50ID0gU2V0SWRlbnQoc3JhdF9vcnQxX2FsbF9pbnQsIHZhbHVlID0gInNwZWNpZXMiKQogIAogIHNyYXRfY3NzX29uZV9sW1tuXV0gPSBzcmF0X29ydDFfYWxsX2ludAp9CmBgYAoKCiMjIENvbWJpbmVkCnJQQ0EgKyBIYXJtb255LCBhbGwgb3J0aG9sb2cKCmBgYHtyfQpzcmF0X3JwY2FfaGFybV9hbGxfbCA9IGxpc3QoKQpmb3IobiBpbiBuYW1lcyhzcmF0X3JwY2FfYWxsX2wpKXsKICBwcmludChuKQogICMgUnVuIEhhcm1vbnkKICBjZWxsX2ludGVnciA9IFJ1bkhhcm1vbnkoc3JhdF9ycGNhX2FsbF9sW1tuXV0sICJzcGVjaWVzIiwgdGF1ID0gMzAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90X2NvbnZlcmdlbmNlID0gRiwgYXNzYXkudXNlID0gIlNDVCIpCiAgCiAgIyBSdW4gVU1BUCBvbiBIYXJtb255IGRpbWVuc2lvbnMKICBjZWxsX2ludGVnciA9IFJ1blVNQVAoY2VsbF9pbnRlZ3IsIHJlZHVjdGlvbiA9ICJoYXJtb255IiwgZGltcyA9IDE6MTApCiAgCiAgc3JhdF9ycGNhX2hhcm1fYWxsX2xbW25dXSA9IGNlbGxfaW50ZWdyCn0KYGBgCgpyUENBICsgSGFybW9ueSwgb25lMm9uZSBvcnRob2xvZwoKYGBge3J9CnNyYXRfcnBjYV9oYXJtX29uZV9sID0gbGlzdCgpCmZvcihuIGluIG5hbWVzKHNyYXRfcnBjYV9vbmVfbCkpewogIHByaW50KG4pCiAgIyBSdW4gSGFybW9ueQogIGNlbGxfaW50ZWdyID0gUnVuSGFybW9ueShzcmF0X3JwY2Ffb25lX2xbW25dXSwgInNwZWNpZXMiLCB0YXUgPSAzMCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3RfY29udmVyZ2VuY2UgPSBGLCBhc3NheS51c2UgPSAiU0NUIikKICAKICAjIFJ1biBVTUFQIG9uIEhhcm1vbnkgZGltZW5zaW9ucwogIGNlbGxfaW50ZWdyID0gUnVuVU1BUChjZWxsX2ludGVnciwgcmVkdWN0aW9uID0gImhhcm1vbnkiLCBkaW1zID0gMToxMCkKICAKICBzcmF0X3JwY2FfaGFybV9vbmVfbFtbbl1dID0gY2VsbF9pbnRlZ3IKfQpgYGAKCkNTUyArIEhhcm1vbnksIGFsbCBvcnRob2xvZwoKYGBge3J9CnNyYXRfY3NzX2hhcm1fYWxsX2wgPSBsaXN0KCkKZm9yKG4gaW4gbmFtZXMoc3JhdF9jc3NfYWxsX2wpKXsKICBwcmludChuKQogICMgUnVuIEhhcm1vbnkKICBjZWxsX2ludGVnciA9IFJ1bkhhcm1vbnkoc3JhdF9jc3NfYWxsX2xbW25dXSwgInNwZWNpZXMiLCB0YXUgPSAzMCwgcmVkdWN0aW9uID0gImNzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbXMudXNlID0gMTpuY29sKEVtYmVkZGluZ3Moc3JhdF9jc3NfYWxsX2xbW25dXSwiY3NzIikpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90X2NvbnZlcmdlbmNlID0gRiwgYXNzYXkudXNlID0gIlNDVCIpCiAgCiAgIyBSdW4gVU1BUCBvbiBIYXJtb255IGRpbWVuc2lvbnMKICBjZWxsX2ludGVnciA9IFJ1blVNQVAoY2VsbF9pbnRlZ3IsIHJlZHVjdGlvbiA9ICJoYXJtb255IiwgZGltcyA9IDE6MTApCiAgCiAgc3JhdF9jc3NfaGFybV9hbGxfbFtbbl1dID0gY2VsbF9pbnRlZ3IKfQpgYGAKCkNTUyArIEhhcm1vbnksIG9uZTJvbmUgb3J0aG9sb2cKCmBgYHtyfQpzcmF0X2Nzc19oYXJtX29uZV9sID0gbGlzdCgpCmZvcihuIGluIG5hbWVzKHNyYXRfY3NzX29uZV9sKSl7CiAgcHJpbnQobikKICAjIFJ1biBIYXJtb255CiAgY2VsbF9pbnRlZ3IgPSBSdW5IYXJtb255KHNyYXRfY3NzX29uZV9sW1tuXV0sICJzcGVjaWVzIiwgdGF1ID0gMzAsIHJlZHVjdGlvbiA9ICJjc3MiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkaW1zLnVzZSA9IDE6bmNvbChFbWJlZGRpbmdzKHNyYXRfY3NzX29uZV9sW1tuXV0sImNzcyIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdF9jb252ZXJnZW5jZSA9IEYsIGFzc2F5LnVzZSA9ICJTQ1QiKQogIAogICMgUnVuIFVNQVAgb24gSGFybW9ueSBkaW1lbnNpb25zCiAgY2VsbF9pbnRlZ3IgPSBSdW5VTUFQKGNlbGxfaW50ZWdyLCByZWR1Y3Rpb24gPSAiaGFybW9ueSIsIGRpbXMgPSAxOjEwKQogIAogIHNyYXRfY3NzX2hhcm1fb25lX2xbW25dXSA9IGNlbGxfaW50ZWdyCn0KYGBgCgojIyBTYXZlIGxpc3RzClNhdmUKCmBgYHtyfQpzYXZlUkRTKHNyYXRfcnBjYV9hbGxfbCwgZmlsZSA9ICIuL2RhdGEvaW50ZWdyYXRpb24vc3JhdF9ycGNhX2FsbF9sLlJEUyIpCnNhdmVSRFMoc3JhdF9ycGNhX29uZV9sLCBmaWxlID0gIi4vZGF0YS9pbnRlZ3JhdGlvbi9zcmF0X3JwY2Ffb25lX2wuUkRTIikKCnNhdmVSRFMoc3JhdF9oYXJtX2FsbF9sLCBmaWxlID0gIi4vZGF0YS9pbnRlZ3JhdGlvbi9zcmF0X2hhcm1fYWxsX2wuUkRTIikKc2F2ZVJEUyhzcmF0X2hhcm1fb25lX2wsIGZpbGUgPSAiLi9kYXRhL2ludGVncmF0aW9uL3NyYXRfaGFybV9vbmVfbC5SRFMiKQoKc2F2ZVJEUyhzcmF0X2Nzc19hbGxfbCwgZmlsZSA9ICIuL2RhdGEvaW50ZWdyYXRpb24vc3JhdF9jc3NfYWxsX2wuUkRTIikKc2F2ZVJEUyhzcmF0X2Nzc19vbmVfbCwgZmlsZSA9ICIuL2RhdGEvaW50ZWdyYXRpb24vc3JhdF9jc3Nfb25lX2wuUkRTIikKCnNhdmVSRFMoc3JhdF9ycGNhX2hhcm1fYWxsX2wsIGZpbGUgPSAiLi9kYXRhL2ludGVncmF0aW9uL3NyYXRfcnBjYV9oYXJtX2FsbF9sLlJEUyIpCnNhdmVSRFMoc3JhdF9ycGNhX2hhcm1fb25lX2wsIGZpbGUgPSAiLi9kYXRhL2ludGVncmF0aW9uL3NyYXRfcnBjYV9oYXJtX29uZV9sLlJEUyIpCgpzYXZlUkRTKHNyYXRfY3NzX2hhcm1fYWxsX2wsIGZpbGUgPSAiLi9kYXRhL2ludGVncmF0aW9uL3NyYXRfY3NzX2hhcm1fYWxsX2wuUkRTIikKc2F2ZVJEUyhzcmF0X2Nzc19oYXJtX29uZV9sLCBmaWxlID0gIi4vZGF0YS9pbnRlZ3JhdGlvbi9zcmF0X2Nzc19oYXJtX29uZV9sLlJEUyIpCmBgYAoKUGxvdHMgZm9yIGFsbCBnZW5lcwoKYGBge3IsIGZpZy5oZWlnaHQ9Ni41LCBmaWcud2lkdGg9MTN9CmZvcihuIGluIG5hbWVzKHNyYXRfcnBjYV9hbGxfbCkpewogIHBsdDEgPSBEaW1QbG90KHNyYXRfcnBjYV9hbGxfbFtbbl1dLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gInNwZWNpZXMiKSsKICAgIGxhYnModGl0bGUgPSBwYXN0ZTAoInJQQ0EsIGFsbCBvcnRob2xvZ3MsICIsIG4pKSsKICBEaW1QbG90KHNyYXRfcnBjYV9hbGxfbFtbbl1dLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gImNsYXNzZXMiKSsKICAgIGxhYnModGl0bGUgPSBwYXN0ZTAoInJQQ0EsIGFsbCBvcnRob2xvZ3MsICIsIG4pKQogIHByaW50KHBsdDEpCiAgCiAgcGx0MiA9IERpbVBsb3Qoc3JhdF9jc3NfYWxsX2xbW25dXSwgcmVkdWN0aW9uID0gInVtYXBfY3NzIiwgZ3JvdXAuYnkgPSAic3BlY2llcyIpKwogICAgbGFicyh0aXRsZSA9IHBhc3RlMCgiQ1NTLCBhbGwgb3J0aG9sb2dzLCAiLCBuKSkrCiAgRGltUGxvdChzcmF0X2Nzc19hbGxfbFtbbl1dLCByZWR1Y3Rpb24gPSAidW1hcF9jc3MiLCBncm91cC5ieSA9ICJjbGFzc2VzIikrCiAgICBsYWJzKHRpdGxlID0gcGFzdGUwKCJDU1MsIGFsbCBvcnRob2xvZ3MsICIsIG4pKQogIHByaW50KHBsdDIpCiAgCiAgcGx0MyA9IERpbVBsb3Qoc3JhdF9oYXJtX2FsbF9sW1tuXV0sIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAic3BlY2llcyIpKwogICAgbGFicyh0aXRsZSA9IHBhc3RlMCgiSGFybW9ueSwgYWxsIG9ydGhvbG9ncywgIiwgbikpKwogIERpbVBsb3Qoc3JhdF9oYXJtX2FsbF9sW1tuXV0sIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAiY2xhc3NlcyIpKwogICAgbGFicyh0aXRsZSA9IHBhc3RlMCgiSGFybW9ueSwgYWxsIG9ydGhvbG9ncywgIiwgbikpCiAgcHJpbnQocGx0MykKICAKICBwbHQ0ID0gRGltUGxvdChzcmF0X3JwY2FfaGFybV9hbGxfbFtbbl1dLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gInNwZWNpZXMiKSsKICAgIGxhYnModGl0bGUgPSBwYXN0ZTAoInJQQ0ErSGFybW9ueSwgYWxsIG9ydGhvbG9ncywgIiwgbikpKwogIERpbVBsb3Qoc3JhdF9ycGNhX2hhcm1fYWxsX2xbW25dXSwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJjbGFzc2VzIikrCiAgICBsYWJzKHRpdGxlID0gcGFzdGUwKCJyUENBK0hhcm1vbnksIGFsbCBvcnRob2xvZ3MsICIsIG4pKQogIHByaW50KHBsdDQpCiAgCiAgcGx0NSA9IERpbVBsb3Qoc3JhdF9jc3NfaGFybV9hbGxfbFtbbl1dLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gInNwZWNpZXMiKSsKICAgIGxhYnModGl0bGUgPSBwYXN0ZTAoIkNTUytIYXJtb255LCBhbGwgb3J0aG9sb2dzLCAiLCBuKSkrCiAgRGltUGxvdChzcmF0X2Nzc19oYXJtX2FsbF9sW1tuXV0sIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAiY2xhc3NlcyIpKwogICAgbGFicyh0aXRsZSA9IHBhc3RlMCgiQ1NTK0hhcm1vbnksIGFsbCBvcnRob2xvZ3MsICIsIG4pKQogIHByaW50KHBsdDUpCn0KYGBgCgpQbG90cyBmb3Igb25lMm9uZSBnZW5lcwoKYGBge3IsIGZpZy5oZWlnaHQ9Ni41LCBmaWcud2lkdGg9MTN9CmZvcihuIGluIG5hbWVzKHNyYXRfcnBjYV9vbmVfbCkpewogIHBsdDEgPSBEaW1QbG90KHNyYXRfcnBjYV9vbmVfbFtbbl1dLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gInNwZWNpZXMiKSsKICAgIGxhYnModGl0bGUgPSBwYXN0ZTAoInJQQ0EsIG9uZTJvbmUgb3J0aG9sb2dzLCAiLCBuKSkrCiAgRGltUGxvdChzcmF0X3JwY2Ffb25lX2xbW25dXSwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJjbGFzc2VzIikrCiAgICBsYWJzKHRpdGxlID0gcGFzdGUwKCJyUENBLCBvbmUyb25lIG9ydGhvbG9ncywgIiwgbikpCiAgcHJpbnQocGx0MSkKICAKICBwbHQyID0gRGltUGxvdChzcmF0X2Nzc19vbmVfbFtbbl1dLCByZWR1Y3Rpb24gPSAidW1hcF9jc3MiLCBncm91cC5ieSA9ICJzcGVjaWVzIikrCiAgICBsYWJzKHRpdGxlID0gcGFzdGUwKCJDU1MsIG9uZTJvbmUgb3J0aG9sb2dzLCAiLCBuKSkrCiAgRGltUGxvdChzcmF0X2Nzc19vbmVfbFtbbl1dLCByZWR1Y3Rpb24gPSAidW1hcF9jc3MiLCBncm91cC5ieSA9ICJjbGFzc2VzIikrCiAgICBsYWJzKHRpdGxlID0gcGFzdGUwKCJDU1MsIG9uZTJvbmUgb3J0aG9sb2dzLCAiLCBuKSkKICBwcmludChwbHQyKQogIAogIHBsdDMgPSBEaW1QbG90KHNyYXRfaGFybV9vbmVfbFtbbl1dLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gInNwZWNpZXMiKSsKICAgIGxhYnModGl0bGUgPSBwYXN0ZTAoIkhhcm1vbnksIG9uZTJvbmUgb3J0aG9sb2dzLCAiLCBuKSkrCiAgRGltUGxvdChzcmF0X2hhcm1fb25lX2xbW25dXSwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJjbGFzc2VzIikrCiAgICBsYWJzKHRpdGxlID0gcGFzdGUwKCJIYXJtb255LCBvbmUyb25lIG9ydGhvbG9ncywgIiwgbikpCiAgcHJpbnQocGx0MykKICAKICBwbHQ0ID0gRGltUGxvdChzcmF0X3JwY2FfaGFybV9vbmVfbFtbbl1dLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gInNwZWNpZXMiKSsKICAgIGxhYnModGl0bGUgPSBwYXN0ZTAoInJQQ0ErSGFybW9ueSwgb25lMm9uZSBvcnRob2xvZ3MsICIsIG4pKSsKICBEaW1QbG90KHNyYXRfcnBjYV9oYXJtX29uZV9sW1tuXV0sIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAiY2xhc3NlcyIpKwogICAgbGFicyh0aXRsZSA9IHBhc3RlMCgiclBDQStIYXJtb255LCBvbmUyb25lIG9ydGhvbG9ncywgIiwgbikpCiAgcHJpbnQocGx0NCkKICAKICBwbHQ1ID0gRGltUGxvdChzcmF0X2Nzc19oYXJtX29uZV9sW1tuXV0sIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAic3BlY2llcyIpKwogICAgbGFicyh0aXRsZSA9IHBhc3RlMCgiQ1NTK0hhcm1vbnksIG9uZTJvbmUgb3J0aG9sb2dzLCAiLCBuKSkrCiAgRGltUGxvdChzcmF0X2Nzc19oYXJtX29uZV9sW1tuXV0sIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAiY2xhc3NlcyIpKwogICAgbGFicyh0aXRsZSA9IHBhc3RlMCgiQ1NTK0hhcm1vbnksIG9uZTJvbmUgb3J0aG9sb2dzLCAiLCBuKSkKICBwcmludChwbHQ1KQp9CmBgYAoKCgoKCgoKCgoKCg==